//
// Created by Dinger on 2021/9/18.
//

#ifndef FUNDAMENTALS_OF_COMPILING_GRAMMAR_H
#define FUNDAMENTALS_OF_COMPILING_GRAMMAR_H

#include"stdafx.h"

using namespace std;

class Symbol {
private:
    string _symbolName;
    bool _isTerminal;
    bool _isSpace;
    bool _isBegin;
    int _symbolNumber;
    int _row;
    int _col;
public:
    Symbol();

    Symbol(string symbolName, bool isTerminal, string beginString);

    Symbol(string symbolName, bool isTerminal, string beginString, int symbolNumber, int row, int col);

    string getSymbolName() {
        return _symbolName;
    }

    bool getIsTerminal() {
        return _isTerminal;
    }

    bool getIsSpace() {
        return _isSpace;
    }

    bool getIsBegin() {
        return _isBegin;
    }

    int getSymbolNumber() {
        return _symbolNumber;
    }

    int getRow() {
        return _row;
    }

    int getCol() {
        return _col;
    }

    void setSymbolName(string symbolName) {
        _symbolName = symbolName;
    }

    void setIsTerminal(bool isTerminal) {
        _isTerminal = isTerminal;
    }

    void setIsSpace(bool isSpace) {
        _isSpace = isSpace;
    }

    void setIsBegin(bool isBegin) {
        _isBegin = isBegin;
    }

    void setSymbolNumber(int symbolNumber) {
        _symbolNumber = symbolNumber;
    }

};

class Tree {
private:
    Symbol _data;
    vector<Tree *> _nodes;
public:
    Tree() {};

    Tree(Symbol data);

    //Tree(Symbol data, vector<Tree> *nodes);

    Symbol getData() {
        return _data;
    }

    vector<Tree *> getNodes() {
        return _nodes;
    }

    void setDate(Symbol data) {
        _data = data;
    }

    void setNodes(vector<Tree *> nodes) {
        _nodes = nodes;
    }
};

class Sentence {
private:
    Symbol _leftPart;
    vector<Symbol> _rightPart;
    string _sentenceString;
    map<string, bool> _legalSymbolNames;
    string _beginString;

    void divideSentenceString();

    void divideRightPart(string rightPartString);

    void divideAttributeAndSymbol(string rightPartString, vector<string> &attributeStrings);

    void attributeStrings2Attribute(vector<string> attributeStrings);

public:
    Sentence();

    Sentence(Symbol leftPart, vector<Symbol> rightPart);

    Sentence(string sentenceString, map<string, bool> legalSymbolNames, string beginString);

    Symbol getLeftPart() {
        return _leftPart;
    }

    vector<Symbol> getRightPart() {
        return _rightPart;
    }

    string getSentenceString(){
        return _sentenceString;
    }
};

class Grammar {
private:
    string _beginSymbolName;
    vector<Sentence> _sentences;
    map<string, bool> _legalSymbolNames;

    /**
     * 读入文件
     * @param fileName 文件名
     */
    void readFile(string fileName);

public:
    Grammar();

    Grammar(string fileName, string beginSymbolName);

    string getBeginSymbolName() {
        return _beginSymbolName;
    }

    vector<Sentence> getSentences() {
        return _sentences;
    }

    map<string, bool> getLegalSymbolNames() {
        return _legalSymbolNames;
    }

    void insertSentence(Sentence sentence) {
        _sentences.push_back(sentence);
    }

    void insertSentences(vector<Sentence> sentences) {
        _sentences.insert(_sentences.end(), sentences.begin(), sentences.end());
    }

    void insertSentences(set<Sentence> sentences) {
        _sentences.insert(_sentences.end(), sentences.begin(), sentences.end());
    }

    void insertLegalSymbolNames(string nameString, bool isTerminal);
};

#endif //FUNDAMENTALS_OF_COMPILING_GRAMMAR_H
